home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d1 / bastips2.arc / BASICNTS.TXT < prev    next >
Text File  |  1988-11-29  |  45KB  |  993 lines

  1.                      Safe Zones in IBM BASIC
  2.                   (COMPUTE! Magazine July 1986)
  3.  
  4.      There is a way to store a few characters or flags in the PC's
  5. memory that will survive the BASIC RUN command.  BASIC's CLEAR command
  6. gives you the ability to create a safe area of RAM of almost any size.
  7. Besides deleting all variables, CLEAR controls the amount of memory
  8. available to BASIC.  By adding a command and a parameter to the CLEAR
  9. command, you can make the BASIC workspace smaller than usual, reserving
  10. the extra memory for yourself.  The workspace is initially 65,536 bytes
  11. but it's easy to reserve some memory at the top of that space.  Use
  12. this format:
  13.  
  14. CLEAR ,workspace
  15.  
  16. where workspace is a number less than 65536.  To calculate the correct
  17. value, subtract from 65536 the number of bytes you want to protect.
  18. For instance, the command, CLEAR ,65280 reserves the last 256 bytes
  19. (65536 - 256 = 65280) of BASIC workspace for your use.  When you type
  20. RUN after a CLEAR statement like this, the size of the workspace is
  21. reset to its default but the data in the reserved area is not affected.
  22. As long as the next program begins with a similar CLEAR statement, it
  23. can PEEK into the reserved area and find the values that the previous
  24. program POKEd there.  Here's a simple program that stores some values
  25. in a 256-byte reserved area:
  26.  
  27. 10 CLEAR ,65280
  28. 20 FOR A=0 TO 255
  29. 30 POKE A+65280,A
  30. 40 NEXT
  31.  
  32. After you run the program, enter and run this program to read the
  33. stored values back:
  34.  
  35. 10 CLEAR ,65280
  36. 20 FOR A=0 TO 255
  37. 30 PRINT PEEK(A+65280)
  38. 40 NEXT
  39.  
  40. -----------------------------------------------------------------
  41.                       Selective BSAVE/BLOAD
  42.         (PC Magazine Vol 5 No 13 July 1986 User-to-User)
  43.  
  44.      Most users who BSAVE and BLOAD BASICA screens do so a full screen
  45. at a time, but it can be very handy to do it in smaller pieces.  The
  46. LITLBSAV.BAS program BSAVEs a little piece of the screen (three lines)
  47. and then lets the user BLOAD it back in various places up and down the
  48. screen.  This technique works very well off a RAMdisk or hard disk but
  49. is slow when run from a floppy.
  50.      Editor's Note:  The program was modified so it BSAVEd three lines
  51. (a line of text with a blank line above and below) and let users move
  52. the BSAVEd block up and down the screen.  (Including blank lines above
  53. and below the printed line effectively erases existing printed lines
  54. on-screen.)  In line 120 the program determines whether the system is
  55. monochrome (where PEEK(1097)=7) or not, and in line 130 sets the
  56. segment to &HB800 for color or &HB000 for mono.  Color systems offer
  57. four screen pages, 0 through 3.  If you have a color system, you can
  58. increase the upper limit in line 200 to 3680 and make the text
  59. temporarily "disappear."
  60.      The nice thing about this technique is that it lets you "pop" up
  61. text onto existing screens.  However, it won't restore the existing
  62. part of the screen it covers over.  Still, by BSAVEing portions of
  63. screens and BLOADing them at the appropriate locations, you save disk
  64. space adn make the BLOAD operation a little faster.
  65.      Since color screen memory is not dual-ported (as mono memory is),
  66. you'll see "chatter" or "snow" while the BLOAD is occurring.  Most snow
  67. is white, so by setting a white (7) background most of it is covered
  68. up.  This will run slower on a disk system unless you hit the Up and
  69. Down Arrow keys rapidly enough to keep the floppy spinning constantly.
  70. These days you can buy slow hard disks for a lot less than $500.  Or
  71. stock up on system RAM and try this in a RAMdisk.
  72.      BSAVCALC.BAS calculates the offset and length for BSAVEs (and the
  73. offset for BLOADs) less than a full screen in size.  The PC text screen
  74. memory is arranged so that each character takes up 2 bytes -- one
  75. representing the actual character, and one for the character's
  76. attribute.  The default text screen is 80 characters wide, so each
  77. 80-wide lien in memory takes up 160 bytes.  Color memory begins at
  78. segment &HB800, mono memory at &HB000.  You tell BASICA which segment
  79. you want with the statement DEF SEG=&HB800 or DEF SEG=&HB000.  BSAVE
  80. needs to know three things -- the filename it will use to store the
  81. screen on your disk, the "offset" (distance in bytes up from the
  82. segment specified by DEF SEG), and the length of the file to save.
  83. Line 1 goes from offset 0 to offset 159, line 2 from 160 to 319, etc.
  84. All BLOAD needs to know is the filename and offset, not the length.
  85.  
  86. 100 'LITLBSAV.BAS
  87. 110 DEFINT A-Z:CLEAR:S$=STRING$(4,205)
  88. 120 DEF SEG=0:IF PEEK(1097)=7 THEN SG=&HB000 ELSE SG=&HB800
  89. 130 DEF SEG=SG:KEY OFF:SCREEN 0,0:COLOR 4,7,6:CLS:LOCATE 2,1,0
  90. 140 PRINT S$;" This BLOADs a line at a time (hit ";CHR$(24):" and ";
  91. 150 PRINT CHR$(25);" keys to move, or ESC to end) ";S$
  92. 160 BSAVE "TEST.SCR",0,480:CLS:S=3680:GOTO 210
  93. 170 I$=INKEY$:IF I$="" THEN 170 ELSE IF I$=CHR$(27) THEN LOCATE 1,1:END
  94. 180 I=INSTR("HP",RIGHT$(I$,1)):IF I=0 OR LEN(I$)=1 THEN BEEP:GOTO 210
  95. 190 IF I=1 THEN IF S<0 THEN BEEP:GOTO 170 ELSE S=S-160:GOTO 210
  96. 200 IF S>3520 THEN BEEP:GOTO 170 ELSE S=S+160
  97. 210 BLOAD "TEST.SCR",S:GOTO 170
  98.  
  99. - - - - -
  100. 100 'BSAVCALC.BAS
  101. 110 DEF FNST$(Z)=MID$(STR$(Z),2+(Z<0)):Q$=CHR$(34):CLS
  102. 120 PRINT "Pick one:  1 - BSAVE  2 - BLOAD  (1 or 2)"
  103. 130 I$=INKEY$:IF I$="" THEN 130 ELSE IF I$=CHR$(13) THEN END
  104. 140 IF INSTR("12",I$)=0 THEN 130 ELSE I=VAL(I$)
  105. 150 IF I=2 THEN B$="BLOAD " ELSE B$="BSAVE "
  106. 160 PRINT CHR$(30);B$;"information:";STRING$(20,32)
  107. 170 INPUT "Enter a start line from 1-25: ",S1
  108. 180 IF S1<1 OR S1>25 THEN BEEP:GOTO 170
  109. 190 IF I=2 THEN PRINT:PRINT "For line";S1:GOTO 230
  110. 200 INPUT "Enter a stop line from 1-25: ",S2
  111. 210 IF S2<1 OR S2>25 OR S2<S1 THEN BEEP:GOTO 200
  112. 220 PRINT:PRINT "For line(s)";S1;"to";S2
  113. 230 OFFSET=(S1-1)*160:LENGTH=(S2*160)-OFFSET
  114. 240 PRINT "Offset =";OFFSET:IF I=2 THEN 260
  115. 250 PRINT "Length =";LENGTH
  116. 260 PRINT "Syntax = ";B$;Q$;"filename";Q$;",";
  117. 270 PRINT FNST$(OFFSET);:IF I=2 THEN 290
  118. 280 PRINT ",";FNST$(LENGTH);
  119. 290 PRINT:PRINT:PRINT STRING$(40,61):PRINT:GOTO 120
  120.  
  121. -----------------------------------------------------------------
  122.                            Value Added
  123.         (PC Magazine Vol 5 No 13 July 1986 User-to-User)
  124.  
  125.      In the IBM BASICA documentation for VAL, the example at the bottom
  126. of the page correctly extracts the house number from an address:
  127.  
  128. PRINT VAL("3408 SHERWOOD BLVD.")
  129.  3408
  130.  
  131. However, if the address happens to be "3408 E 9th Street," VAL returns
  132. the number 3048000000000, as it interprets the "E" as the exponential
  133. part of the number.  This also occurs with a D.
  134.      You can prevent trouble by putting periods after the E or D.
  135.  
  136. PRINT VAL("3408 E. 9th Street")
  137.  
  138. works properly.
  139.  
  140. -----------------------------------------------------------------
  141.                   Automatic IBM Screen Printing
  142.                  (COMPUTE! Magazine August 1986)
  143.  
  144.      You can add a Print Screen function to any program by POKEing a
  145. tiny machine language into a reserved space at the top of BASIC's
  146. memory area.  The ML just executes INT5:RETF to call the Print Screen
  147. routine and returns to BASIC.
  148.      When incorporating this routine into your program(s), the line
  149. with the CLEAR statement must be the first line in your program.
  150. Otherwise, any previously defined variables will be erased.  Once the
  151. machine language is POKEd into memory, your program can execute the
  152. statement CALL PRTSC to make a printout.
  153.  
  154. 100 CLEAR ,&HFFF0:PRTSC=&HFFF0
  155. 110 DEF SEG:FOR X=0 TO 2:READ N:POKE X+PRTSC,N:NEXT
  156. 120 DATA &HCD,&H05,&HCB
  157. 200 CALL PRTSC
  158.  
  159. -----------------------------------------------------------------
  160.                    Batch Files with IBM BASIC
  161.     (COMPUTE! Magazine August 1986 by Lawrence H. Bannister)
  162.  
  163.      IBM users know that you can save time by using the batch commands
  164. of DOS to perform a sequence of DOS commands automatically.  But the
  165. austere language of DOS provides only three variations of one simple
  166. IF statement and has no practical way at all of manipulating strings
  167. or performing arithmetic.  It's difficult to write a batch file that
  168. creates neat screen displays, makes logical branches, allows user
  169. input, and traps errors.
  170.      A more flexible technique is to call DOS commands or even batch
  171. files from with a BASIC program.  This frees you from the limitations
  172. of batch files and takes advantage of the string and arithmetic
  173. functions of BASIC.
  174.      You can call DOS from BASIC as often as you wish by using the
  175. SHELL command found in IBM BASICA.  Although it is not documented,
  176. this command is implemented in version 2.1 or higher of DOS.  Aside
  177. from a few small problems to be avoided, its possibilities are limited
  178. only by your imagination.
  179.      To demonstrate some of these possibilities, the BASIC Batch Demo
  180. program below displays two menus of options, interprets the user's
  181. responses, and then calls a variety of DOS routines in several
  182. different ways.  The Batch File for Demo is a short batch file that
  183. is required as part of this demonstration.
  184.      When you run the BASIC program, it shows a menu offering four
  185. choices:
  186.  
  187. MENU A:
  188. 1. Show system date
  189. 2. Show system time
  190. 3. Show system date and time
  191. 4. None of the above
  192. Enter your choice:
  193.  
  194.      When the user presses a key, the program checks to see if the
  195. keypress was 1, 2, 3, or 4, and if so, uses the SHELL command to call
  196. the appropriate DOS function:  DATE, TIME, or the batch file that calls
  197. both DATE and TIME.
  198.      When DOS returns control to BASIC, the program displays a second
  199. menu:
  200.  
  201. MENU B:
  202. 1. Run Checkdisk
  203. 2. Show Disk Directory
  204. 3. None of the above
  205. Enter your choice:
  206.  
  207.      This is similar to the first menu, except this time the program
  208. calls a DOS function that requires a parameter to be passed to the DOS
  209. command line.  The BASIC program asks the user for the necessary
  210. information, then concatenates the appropriate command-line string.
  211.      Notice that the SHELL command can pass either a literal string,
  212. as done in the first menu, or a string variable, as in the response
  213. to the second menu.
  214.      There are two considerations to keep in mind when using this
  215. technique.  First, make sure your system has enough memory.  Although
  216. DOS, BASICA, and your BASIC program can be loaded into a machine with
  217. as little as 64K of RAM, you won't have much memory left over to do
  218. anything very useful.  At least 92K RAM is desireable, because DOS and
  219. BASICA together use about 90K if that much is available.  You need
  220. still more memory if you also want to run a batch file that calls a
  221. lengthy program like EDLIN.
  222.      Second, be sure not to create a sequence that is reentrant or
  223. recursive.  For example, the result will be unpredictable if you BASIC
  224. program calls a batch file that, in turn, calls BASIC.  Reentrant
  225. sequences of this nature are apt to cause a system crash that can be
  226. remedied only by turning off the power.
  227.      A minor aggravation is that DOS scrolls 25 lines on the screen
  228. while BASIC scrolls only 24 lines due to the function key display on
  229. the 25th line.  Furthermore, BASIC and DOS each maintain an independent
  230. pointer to the screen position of the cursor.  These differences can
  231. cause BASIC PRINT statements to overwrite something that DOS has just
  232. printed.
  233.      To avoid this problem, always start the BASIC program with the
  234. KEY OFF command to turn off BASIC's function key display.  Then use a
  235. CLS command each time that DOS returns control to BASIC, or, as shown
  236. in the sequence following the second menu in the BASIC Batch Demo
  237. program, surround the SHELL commands with LOCATE 24,1 statements and
  238. two blank PRINT lines to ensure that both DOS and BASIC always start
  239. scrolling from the bottom of their own screens.
  240.  
  241. BASIC Batch Demo Program:
  242.  
  243. 1000 'Procedure Description
  244. 1010 'Clear screen and display a menu offering four choices
  245. 1020 'Wait for user response
  246. 1030 'If user response is not valid
  247. 1040 'Then : display error message and repeat the menu
  248. 1050 'Else :
  249. 1060 'Invoke the selected DOS function or Batch file
  250. 1070 'Clear screen and display a second menu
  251. 1080 'Wait for user response
  252. 1090 'If user response is not valid
  253. 1100 'Then : display error message and repeat the menu
  254. 1110 'Else :
  255. 1120 'Invoke the selected DOS function or program
  256. 1130 '
  257. 1140 '
  258. 1150 KEY OFF:CLS
  259. 1160 GOTO 1210
  260. 1170 '
  261. 1180 PRINT    'Error message
  262. 1190 PRINT "* * * * * * * ILLEGAL RESPONSE  ^   REDO"
  263. 1200 '
  264. 1210 PRINT:PRINT "MENU A:"  'Display menu
  265. 1220 PRINT:PRINT "1. Show system date"
  266. 1230 PRINT:PRINT "2. Show system time"
  267. 1240 PRINT:PRINT "3. Show system date and time"
  268. 1250 PRINT:PRINT "4. None of the above"
  269. 1260 PRINT:PRINT:INPUT "Enter your choice: ",A$
  270. 1270 '
  271. 1280 IF A$="" THEN 1180   'Check response
  272. 1290 IF ASC(A$)<49 THEN 1180
  273. 1300 IF ASC(A$)>52 THEN 1180
  274. 1310 '
  275. 1320 IF A$="1" THEN SHELL "DATE"
  276. 1330 IF A$="2" THEN SHELL "TIME"
  277. 1340 IF A$="3" THEN SHELL "PROG2"
  278. 1350 '
  279. 1360 CLS
  280. 1370 GOTO 1410
  281. 1380 '
  282. 1390 PRINT "* * * * * * * ILLEGAL RESPONSE  ^   REDO"
  283. 1400 '
  284. 1410 PRINT:PRINT "MENU B:"
  285. 1420 PRINT:PRINT "1. Run Checkdisk"
  286. 1430 PRINT:PRINT "2. Show Disk Directory"
  287. 1440 PRINT:PRINT "3. None of the above"
  288. 1450 PRINT:PRINT:INPUT "Enter your choice: ",A$
  289. 1460 PRINT
  290. 1470 '
  291. 1480 IF A$="" THEN 1390
  292. 1490 IF ASC(A$)<49 THEN 1390
  293. 1500 IF ASC(A$)>51 THEN 1390
  294. 1510 '
  295. 1520 IF A$="3" THEN 1630
  296. 1530 IF A$="1" THEN B$="CHKDSK"
  297. 1540 IF A$="2" THEN B$="DIR"
  298. 1550 INPUT "Enter drive letter: ",C$
  299. 1560 IF C$="" THEN 1550
  300. 1565 X=ASC(C$+CHR$(0)):IF X<65 OR X>66 THEN 1550
  301. 1570 D$=B$+LEFT$(C$,1)+":"
  302. 1580 LOCATE 24,1
  303. 1590 IF A$="1" THEN GOSUB 1710
  304. 1600 SHELL D$
  305. 1610 PRINT:PRINT
  306. 1620 '
  307. 1630 PRINT "End of BASICA program, returning to SYSTEM"
  308. 1640 PRINT
  309. 1650 PRINT TAB(20) "Normally would return to SYSTEM here,"
  310. 1660 PRINT TAB(20) "but for debug and demo purposes the"
  311. 1670 PRINT TAB(20) "program will restart after a delay"
  312. 1680 FOR I=1 TO 5000:NEXT I:RUN
  313. 1690 '
  314. 1700 '
  315. 1710 PRINT
  316. 1720 PRINT "WARNING: You will get error message `Bad command ...'"
  317. 1730 PRINT "          if the called program is not on "
  318. 1740 PRINT "          the disk in the default drive"
  319. 1750 RETURN
  320.  
  321.  
  322. Batch File for Demo:
  323.  
  324. ECHO OFF
  325. ECHO .
  326. REM Display the system date
  327. DATE
  328. ECHO .
  329. REM Display the system time
  330. TIME
  331. :ENDPROG2
  332.  
  333. -----------------------------------------------------------------
  334.                          BASIC Debugging
  335.              (PC Magazine August 1986 User-to-User)
  336.  
  337.      BASIC is great for interactive programming, but its debugging
  338. tools are quite primitive.  One of the most irritating limitations is
  339. that when you make a simple correction to a single line (even a REMark)
  340. BASIC flushes all your variables, closes all your files, and forces you
  341. to start the program over to test the correction.
  342.      When the interpreter finds an error, it prints an error message
  343. and halts the program.  In many cases, you could continue running the
  344. program if only you could re-enter the offending line and re-execute
  345. it.  To make such on-the-fly corrections, examine the erroneous line
  346. with the LIST command.  (The problem line will already be displayed if
  347. it contains a syntax error.)  Then type the following command in
  348. direct mode:
  349.  
  350. CHAIN MERGE "CON",ERL,ALL
  351.  
  352.      The cursor will drop down to the next line and wait for keyboard
  353. input.  Next, rekey the bad line, and press Enter and then Ctrl-Z and
  354. then Enter again.  The program will continue where it left off.  The
  355. next time you list or save the program, it will contain the repaired
  356. program line.
  357.      Another tip on smart BASIC debugging is to avoid error traps (ON
  358. ERROR GOTO) unless they are absolutely necessary.  They tend to hide
  359. errors that need to be caught, and you will find yourself unable to
  360. get to the root of a malfunction.  Programs can trap errors right at
  361. the source, and then turn error trapping off as soon as possible.
  362. For example:
  363.  
  364. 100 'Print report
  365. 110 ON ERROR GOTO 130
  366. 120 GOTO 150
  367. 130 PRINT "Printer ERROR.  Hit a key."
  368. 140 WHILE INKEY$="":WEND:RESUME
  369. 150 LPRINT "ABC Company Report"
  370. 160 ON ERROR GOTO 0
  371. 170 '...print rest of report ....
  372.  
  373.      This example assumes that any printer errors will surface during
  374. the printing of the first line of a report.  The error trap itself
  375. resides directly above the possible error, and error trapping is on
  376. only during the printing of that line.  Use a similar layout when
  377. opening files.  Printer and disk I/O are about the only places that
  378. an error trap is really needed.  You can write program code to test
  379. for any other potential problems without resorting to BASIC's error
  380. handling.
  381.      Editor's Note:  Using CHAIN MERGE "CON" to fix a BASIC problem
  382. without shutting down the active program is a handy trick.  Your
  383. cursor may temporarily disappear while you're entering the new line,
  384. and you may have to hit the Esc key to erase a message on the screen
  385. before you type in the CHAIN MERGE... command, but the technique can
  386. save a tremendous amount ot time.  Note that while this will correct
  387. the problem line in memory, be sure to save the file to disk to make
  388. the correction permanent.
  389.      In the report-printing routine, you might want to test the error
  390. that BASIC catches with an IF ERR=25 THEN... or IF ERL=150 THEN... to
  391. make sure that the actual problem isn't falsely reported as a printer
  392. error when it's caused by something else.  However, it is right to
  393. trap all the usual errors by writing thorough code, not by skimping
  394. on traps and waiting for a mistake to fall through to an ON ERROR
  395. statement.
  396.  
  397. -----------------------------------------------------------------
  398.                         Refreshing PAUSE
  399.              (PC Magazine August 1986 User-to-User)
  400.  
  401.      To pause for a keystroke in BASICA, most programmers use either
  402.  
  403. 10 A$=INEKY$:IF A$="" THEN 10
  404.  
  405. or
  406.  
  407. 10 WHILE INKEY$:WEND
  408.  
  409. A more natural way is to create a machine language subroutine at the
  410. beginning of your program and then call it whenever required.  Simply
  411. insert the following code at the start of any program:
  412.  
  413. 0 CLEAR,5888
  414. 1 DEF SEG=5888
  415. 2 FOR X.=0 TO 6
  416. 3 READ Y.
  417. 4 POKE X.,Y.
  418. 5 NEXT
  419. 6 PAUSE=0
  420. 7 DATA 80,180,7,205,33,88,203
  421.  
  422. and then adda a
  423.  
  424. 100 CALL PAUSE
  425.  
  426. (substituting the appropriate line number for the 100) whenever you
  427. want to wait for a keystroke.  The example here takes up seven lines,
  428. but you can use colons to concatenate it all to a single line starting
  429. with 0 and save the line as an ASCII file, then merge this file into
  430. any of your existing programs.  The X. and Y. variables and line number
  431. 0 are uncommon so that they don't interfere with ones already in your
  432. programs.
  433.      The key you hit to break the pause is not stored in the keyboard
  434. buffer after the program execution continues.  If you need to read the
  435. key, change the "7" to a "1" in the DATA statement in line 7.
  436.      Editor's Note:  This may be more natural than the usual methods,
  437. but it doesn't really work any better and won't compile as is.  If you
  438. try it and do want the keystroke to print, after changing the 7 to 1
  439. in the DATA statement, follow the CALL PAUSE with a
  440.  
  441. 200 PRINT INKEY$
  442.  
  443. (substituting the appropriate line number for the 200).
  444.  
  445. -----------------------------------------------------------------
  446.                        Compaq Unprotection
  447.              (PC Magazine August 1986 User-to-User)
  448.  
  449.      It's simple to modify the technique for unprotecting BASIC
  450. programs described in PC Mag Vol 4 No 25 User-to-User and PC Mag Vol 5
  451. No 10 PC Tutor to work on non-IBM versions of BASIC.  Instead of IBM's
  452. location 1124, use 1228 for Compaq BASIC 2.11, and 1433 for Compaq
  453. BASIC 3.11.  If the location is included in the BSAVE ooperation, you
  454. may omit it from the BLOAD.  Other non-IBM, non-Compaq versions of
  455. MS-BASIC may use entirely different locations.
  456.      Editor's Note:  "Protecting" a BASIC file by saving it with the
  457. ",p" option doesn't really do much other than prevent naive users from
  458. listing the source code.  The technique to remove the flimsy protection
  459. is to get into BASIC and typing:
  460.  
  461. BSAVE "UN.P",1124,1
  462.  
  463. (substituting location 1228 or 1433 if you're using Compaq BASIC 2.11
  464. or 3.11, respectively).  If you every try to list a BASIC program and
  465. see an "Illegal function call" message, just type:
  466.  
  467. BLOAD "UN.P"
  468.  
  469. At this point you should be able to list the source code.  If not, make
  470. sure you tried the proper offset (1228 or 1433) for the BASIC version
  471. you're using.  Then resave the formerly protected BASIC program to
  472. remove the effects of the ",p" permanently.
  473.  
  474. -----------------------------------------------------------------
  475.                         STRING$ and CHR$
  476.                (COMPUTE! Magazine September 1986)
  477.  
  478.      The statement PRINT STRING$(15,32) has exactly the same effect as
  479. PRINT "               " (15 spaces).  STRING$ can be used where any
  480. long series of identical characters is needed.  For instance, PRINT
  481. STRING$(40,46) prints a line consisting of 40 dots.
  482.      You can also do the same thing through concatenation.  To create
  483. a string consisting of 30 spaces, for instance, use:
  484.  
  485. SP$=" "
  486. FOR J=1 TO 30
  487. SP$=SP$+CHR$(32)
  488. NEXT
  489.  
  490. This construction is easy to type and requires only a few more
  491. characters than printing the string in literal form.
  492.  
  493. -----------------------------------------------------------------
  494.                        BASIC Configuration
  495.              (PC World September 1986 Star-Dot-Star)
  496.  
  497.      A short BASIC program can define BASIC's function keys and then
  498. erase itself from memory.  A short batch file can start BASIC and run
  499. this program automatically so that your custom function key assignments
  500. are in place.
  501.      Defining the function key settings in this manner also lets you
  502. use the following time-saving trick.  Whenever you write a BASIC
  503. program, always put a comment on line 1 beginning with the program's
  504. name enclosed in quotes.  Combining this step with the F10 definition
  505. show in BSTART.BAS enables you to save a program anytime with one
  506. quick keystroke.
  507.      The first part of F10's definition, "LIST 1"+CHR$(13), simply
  508. lists the first line of the current program -- the line containing the
  509. program's name.  The two CHR$(30) characters move the cursor back to
  510. the beginning of the listed line.  SAVE overwrites the line number and
  511. the apostrophe, leaving the file name in quotation marks intact.  The
  512. last CHR$(13) simulates pressing Enter, executing the SAVE command
  513. using the supplied file name.
  514.      This technique should be a boon to anyone who issues SAVE commands
  515. frequently, since it reduces that task to a single keystroke.  If you
  516. prefer to save your programs in ASCII format you can place the ,A after
  517. whatever file name you specify.
  518.  
  519. -----------------------------------------------------------------
  520.                       IBM Custom Characters
  521.                (COMPUTE! Magazine September 1986)
  522.  
  523.      You can redefine the character set on the IBM PC; however, there
  524. are a couple of restrictions.  Redefined characters must be printed on
  525. one of the graphics screens to be seen, and only the upper half of the
  526. character set (characters 128-255) can be changed.  The following
  527. program shows how to redefine CHR$(128) as an alien shape.  It displays
  528. the custom character on SCREEN 1.
  529.  
  530. 10 DEF SEG=0
  531. 20 POINTER=&H7C    'POINTER &H110 for characters 0-127 on the PCjr only
  532. 30 FOR VECTOR=0 TO 3:OLDVEC(VECTOR)=PEEK(POINTER+VECTOR):NEXT
  533. 40 DEF SEG=&H1700
  534. 50 FOR DOTPOS=0 TO 7:READ DOT DATA:POKE DOTPOS,DOTDATA:NEXT
  535. 60 DEF SEG=0:
  536. 70 SCREEN 1:CLS
  537. 80 FOR VECTOR=0 TO 2:POKE(POINTER+VECTOR),0:NEXT:POKE POINTER+3,&H17
  538. 90 PRINT CHR$(128)
  539. 100 FOR VECTOR=0 TO 3:POKE(POINTER+VECTOR),OLDVEC(VECTOR):NEXT
  540. 110 DATA 60,126,90,126,60,36,66,129
  541.  
  542.     You make the computer look to RAM rather than ROM for its character
  543. data.  If you have at least 128K of RAM in your PC, memory above 96K is
  544. unused by BASIC and is thus a safe place to store the custom character
  545. data.  Line 40 of the program accesses this area with the statement
  546. DEF SEG=&H1700.  In line 50, the program puts the alien shape data in
  547. the area beginning at &H1700.  Line 110 contains the data.
  548.     To make the PC fetch its character data from the segment at &H1700,
  549. we must change certain pointers at the bottom of memory. These pointers
  550. are four bytes long.  The first two bytes represent an offset to the
  551. segment address contained in the third and fourth bytes.  The pointer
  552. to the data for the built-in graphics and foreign language characters
  553. (numbered 128-255) is at locatino &H7C.  Since the program redefines a
  554. character in this range -- CHR$(128) -- we've used this pointer value
  555. in line 20.  On the PCjr, you can redefine characters in the range
  556. 0-127 using the pointer at location &H110.  In order to access either
  557. character data pointer, you must set DEF SEG to zero since the pointers
  558. are at the bottom of memory.  The program does this in lines 10 and 60.
  559.      Before the program ends, the character data pointers must be
  560. restored to their default values.  If you end the program with the
  561. character pointers still modified, the computer can't recognize the
  562. custom characters and will fail to respond to any commands.  Before
  563. modifying the characters, save the default character set pointers
  564. (line 30).  When you're done printing the custom characters, restore
  565. the pointers to their original values (line 100).
  566.  
  567. -----------------------------------------------------------------
  568.                       Identifying Displays
  569.         (PC Magazine Vol 5 No 16 Sept 30, 1986 PC Tutor)
  570.  
  571.      A user develops applications with the BASIC interpreter and
  572. compiles them with Microsoft QuickBASIC.  He uses a technique to blank
  573. the screen while text is being written to it.  This results in a nice,
  574. professional-looking video screen that flashes on all at once, rather
  575. than visibly being drawn one line at a time.  To turn the display off,
  576. use the statement:
  577.  
  578. OUT 984,1
  579.  
  580. and to turn it back on:
  581.  
  582. OUT 984,41
  583.  
  584.      This works perfectly with an IBM or compatible color graphics
  585. adapter.  The problem is that the programs must also run on some
  586. Hercules Graphics Cards (and Hercules clones), and the technique
  587. doesn't work with these boards.  Different video pages are also used
  588. in the programs, and these, too, are ignored by the Hercules card.
  589.      Editor's Note:  This technique won't work on regular IBM Mono
  590. Adapters, either.  The port being manipulated is the "Mode Control
  591. Port Register," which has a different address on color adapters and
  592. monochrome adapters, including the Hercules Graphics Card.  The Control
  593. Port for monochrome displays is at address 952 rather than 984.  (In
  594. hex, these addresses are 3B8 and 3D8.)
  595.      You can blank an IBM Monochrome Adapter or Hercules Card with:
  596.  
  597. OUT 952,1
  598.  
  599. and unblank it with:
  600.  
  601. OUT 952,41
  602.  
  603. but that's not the best way to do it.
  604.      The control port address is always 4 higher than the I/O address
  605. of the 6845 video chip.  That port address is a word (2 bytes) stored
  606. at the hex address 0040:0063 in the BIOS data area.  So, you can
  607. define a variable for the Control Port thus:
  608.  
  609. DEG SEG=&H40
  610. CTRLPORT=4+256*PEEK(&H64)+PEEK(&h63)
  611.  
  612. Now you can simply use the variable CTRLPORT instead of 984 or 952.
  613.      You won't be able to use separate video pages on an IBM Monochrome
  614. Adapter or the Hercules Graphics Card, however; so unless you want to
  615. write alternative code for the monochrome boards, it's easier to avoid
  616. using video pages altogether.  (If you must use video pages, you can
  617. still use the value of CTRLPORT to also identify the type of adapter.)
  618.      In general, however, the best way for your programs to identify
  619. the video display is to ask the user on-screen.  This is nothing to
  620. be ashamed of.  You'll find that most software that does anything
  621. beyond plain vanilla text output requires some sort of installation
  622. program.  Some really big-league stuff like Microsoft Word can adapt
  623. to different displays without being told, but then we're talking about
  624. a 44K WORD.COM program (version 3.0) that identifies displays and
  625. provides drivers for them.  We're also talking about problems by
  626. experts in the field.  Further, we're about to see a real explosion
  627. in video adapters, and it's going to get tougher and tougher to write
  628. programs that work with all of them.  The EGA is just the beginning.
  629. (The above technique of blanking the screen won't work on an EGA, but
  630. it won't do any harm, either.)  This is one reason why the graphics
  631. device interface of Microsoft Windows is so important to the future
  632. of the PC.  Windows takes on the responsibility of dealing with the
  633. hardware so that you can concentrate on the program.
  634.  
  635. -----------------------------------------------------------------
  636.                    BSAVE Image Arrays to Disk
  637.              (PC World October 1986 The Help Screen)
  638.  
  639.      Recording a BASIC image array in a disk file and reading that
  640. file to set an image variable is simpler than using GET and PUT.  To
  641. save an image array to disk, issue the DEF SEG statement to set BASIC's
  642. data segment as the current memory segment, and execute the BSAVE
  643. (binary save) command.
  644.      The BSAVE command, which saves any portion of memory to disk,
  645. requires three parameters: the filespec of the file being saved, the
  646. offset (number of bytes) into the current memory segment where the
  647. first byte of data representing the image begins, and the number of
  648. bytes to be saved.
  649.      The filespec requires a file name, but it can include a drive
  650. specifier and, with BASIC 2.0 and later versions, a path.  The offset
  651. should point to the beginning of the image array variable.  You
  652. accomplish this by specifying the array's first element, (0), with the
  653. VARPTR function.  You already know the size of the variable array
  654. because you had to calculate the number of bytes that the image array
  655. required to properly DIMension the array.  In this example, the image
  656. is 34 bytes.  Because a single-precision array dedicates 4 bytes per
  657. element, a nine-element array will reserve sufficient space.
  658.      BSAVE.BAS also demonstrates how to load a saved image array.
  659. Issue a DEF SEG statement to set BASIC's data segment as the current
  660. memory segment, then execute the BLOAD (binary load) command to put
  661. the image data into memory.  BLOAD requires just two parameters: the
  662. filespec and the offset of the current memory segment where the image
  663. file should be placed.  Point to the beginning of the image array
  664. variable with the aid of the VARPTR function.
  665.  
  666. BSAVE.BAS:
  667.  
  668. 10 SCREEN 1:CLS
  669. 20 LINE (0,0)-(10,10),3,B
  670. 30 CIRCLE (5,5),5,1
  671. 40 PAINT (5,5),2,1
  672. 50 DIM IMAGE(22)
  673. 60 GET (0,0)-(10,10),IMAGE
  674. 70 DEF SEG
  675. 80 BSAVE "IMAGE.FIL",VARPTR(IMAGE(0)),88
  676. 90 ERASE IMAGE
  677. 100 DIM IMAGE(22)
  678. 110 DEF SEG
  679. 120 BLOAD "IMAGE.FIL",VARPTR(IMAGE(0))
  680. 130 PUT (100,100),IMAGE
  681. 140 LOCATE 13
  682.  
  683. -----------------------------------------------------------------
  684.                         Personalized DATA
  685.        (PC Magazine Vol 5 No 20 Nov 25, 1986 User-to-User)
  686.  
  687.      STAMP.BAS (PC Mag Vol 5 No 8 April 29, 1986) demonstrated how to
  688. modify a comment permanently from within a BASIC program.  It's also
  689. possible to modify a quoted string in an assigned statement or DATA
  690. statement, since the BASIC interpreter will set up the string variable
  691. to point into the program itself when the string is assigned to, or
  692. read to, a string variable.
  693.      UPDATER.BAS asks for the user's name, displaying the name that is
  694. already loaded in the DATA statement as the default.  If the user then
  695. simply hits the Return key, the program accepts the default; otherwise
  696. the program stores the replacement name in the DATA statement and then
  697. saves itself.  CVI is used to for the string, since this technique
  698. avoids possible overflow errors that can result from multiplication.
  699.      Editor's Note:  This kind of trick can come in handy when adding
  700. new information on the fly, but be careful with it since it can also
  701. write bad data over good data.  You can get around this by adding a
  702. line to the program that saves a backup "UPDATER.BAK" file to disk
  703. before it makes any of the changes in memory and then writes the
  704. permanently changed file.
  705.  
  706. 100 'UPDATER.BAS
  707. 110 READ DUMMY$
  708. 120 PRINT "Enter your name: [";DUMMY$;"]"
  709. 130 LINE INPUT I$
  710. 140 IF I$="" THEN END ELSE I$=I$+SPACE$(19)
  711. 150 P%=VARPTR(DUMMY$)
  712. 160 L%=PEEK(P%)
  713. 170 A%=CVI(CHR$(PEEK(P%+1))+CHR$(PEEK(P%+2)))
  714. 180 FOR I%=1 TO L%
  715. 190 POKE A%+I%-1,ASC(MID$(I$,I%))
  716. 200 NEXT
  717. 210 SAVE "UPDATER
  718. 220 DATA "User name goes here"
  719.  
  720. -----------------------------------------------------------------
  721.                     BASIC and the Environment
  722.          (PC Magazine Vol 5 No 20 Nov 25, 1986 PC Tutor)
  723.  
  724.      You can use the undocumented feature of batch files that allows
  725. treating environment strings as replaceable parameters.  With this
  726. you can let batch files know which device drivers are currently loaded
  727. and to prevent running incompatible resident programs.  For instance,
  728. to load a mouse driver, your AUTOEXEC.BAT file can execute:
  729.  
  730. SET MOUSE=1
  731.  
  732. Then you can do things in batch files like:
  733.  
  734. IF "%MOUSE%"="1" some command
  735. IF NOT "%MOUSE%"="1" some other command
  736.  
  737.      Getting at the environment in BASIC is different.
  738.  
  739.      Editor's Note:  This is a good use of the environment, except it
  740. doesn't work right under DOS 3.0.  DOS 2.x, 3.1 and 3.2 handle it fine.
  741.      The segment address of the environment is always stored at offset
  742. &H002C of the Program Segment Prefix (PSP) of any program.  So, if you
  743. could find the segment address of BASICA.COM's PSP (which will be
  744. different depending on which resident programs and device drivers were
  745. loaded), you could directly access the environment with PEEK.  This
  746. would be messy and probably involve some assembly language routines.
  747.      There's a better way, and that is to upgrade to DOS 3.1 or later.
  748. The new BASICA 3.0 ENVIRON$ function retrieves strings from the
  749. environment based either on the parameter name (such as "PATH") or on
  750. a number.  The small program below shows both approaches.  The WHILE
  751. loop in the first part displays the same information as the DOS SET
  752. command executed without parameters.
  753.  
  754. 10 I=1
  755. 20 WHILE ("" <> ENVIRON$(I))
  756. 30   PRINT ENVIRON$(I)
  757. 40   I=I+1
  758. 50 WEND
  759. 60 PRINT "The COMSPEC is ";ENVIRON$("COMSPEC")
  760.  
  761. -----------------------------------------------------------------
  762.                       Doing a DIR in BASIC
  763.          (PC Magazine Vol 5 No 20 Nov 25, 1986 PC Tutor)
  764.  
  765.      How do you read a diskette directory information into an array
  766. from a BASIC program, and how do you invoke a Print-Screen from within
  767. a program automatically?
  768.  
  769.      Editor's Note:  A very common method used by BASIC programmers for
  770. reading the directory is no more elegant than:
  771.      1) Clear the screen with CLS
  772.      2) Do a FILES command to display a directory on the screen
  773.      3) Read the information off the screen character by character with
  774. a combination of the LOCATE statement and teh SCREEN function.  (The
  775. SCREEN function reads characters from the screen; there is also a
  776. SCREEN statement used for setting video modes.)
  777.     If you'd rather not have the users of your program know what you're
  778. doing, you can use the COLOR statement to set the same foreground and
  779. background colors so nobody can see the FILES display. (The information
  780. is still there, of course.)
  781.      You might also consider another method using the SHELL command,
  782. which is documented under BASIC 3.0 and works most of the time under
  783. BASIC 2.0.  The SHELL command executes another program or a DOS command
  784. from BASIC.  Your line would read:
  785.  
  786. SHELL ("DIR > DIRLIST")
  787.  
  788. This puts a normal DIR listing into a file called DIRLST.  You can then
  789. read the DIRLIST file normally and extract the information you want.
  790.     Other than these approaches, you'd probably have to use an assembly
  791. language subroutine.  This would definitely be more complex than either
  792. of the two methods described above.  BASIC is not the only high-level
  793. language that has no built-in facility for obtaining directory
  794. information: Turbo Pascal and Microsoft C 3.0 don't either.
  795.     Doing a Print-Screen from a BASIC program is much easier.  In fact,
  796. the BASIC 3.0 manual shows two methods for doing it in Appendix B on
  797. assembly language subroutines. The BIOS Print Screen routine is invoked
  798. by an Interrupt 5, which in assembly language takes just two bytes:
  799. &HCD and &H05.  An assembly language routine in BASIC needs only one
  800. more byte, an &HCB, which is a far return back to the main BASIC
  801. program.  You can determine the bytes needed for an assembly language
  802. routine by going into DEBUG assemble mode with the A command and
  803. typing:
  804.  
  805. INT 5
  806. RETF
  807.  
  808. and then listing the bytes with the D command.
  809.     To get these bytes into a BASIC listing, first DIMension an integer
  810. array and store the assembly language code in it:
  811.  
  812. 10 DIM APRTSC%(2)
  813. 20 APRTSC%(1)=&H05CD
  814. 30 APRTSC%(2)=&H90CB
  815.  
  816. Each integer can store 2 bytes.  (Note that the integers are stored in
  817. reverse order, with the most significant byte higher in memory.)  The
  818. extra &H90 at the end is a NOP instruction, which does nothing.
  819.      After the array is set up, use the VARPTR function to find the
  820. address of the array in memory and store it in another variable:
  821.  
  822. 40 PRTSC%=VARPTR(APRTSC%(1))
  823.  
  824. Now you need only CALL that variable:
  825.  
  826. 50 CALL PRTSC%
  827.  
  828. and your screen will be printed.
  829.  
  830. -----------------------------------------------------------------
  831.                         IBM PC One-Liner
  832.            (COMPUTE! December 1986 by Paul W. Carlson)
  833.  
  834.      Programs don't have to be long to be useful.  The one-line program
  835. below can be used to entertain pre-schoolers, while teaching them the
  836. alphabet and the computer's keyboard at the same time.  Adults can
  837. benefit from the program by gaining an increased understanding of how
  838. characters are produced on the IBM's video display.  However it's used,
  839. the program is certainly worth the time it takes to type in the single
  840. line.
  841.      When you run it, nothing seems to happen.  Now press any key on
  842. the keyboard.  A giant character matching the key you pressed rises
  843. from the bottom of the screen and centers itself on the display.
  844. Press another key.  The same thing happens and continues happening
  845. until you press Ctrl-Break.
  846.      The program enlarges all the letters (uppercase and lowercase),
  847. symbols, and punctuation that appears on the keyboard -- plus a few
  848. that don't appear on the keycaps.  If you press Ctrl along with a
  849. letter or number key, you'll see one of the IBM's graphics characters.
  850. Even the function keys produce results.  Try pressing F1.
  851.      Despite its small size, the program contains some techniques you
  852. may find useful in other programs.
  853.      1.  The program begins by setting the segment to location $FFA6.
  854. This is 14 bytes before the PEL (character definition) map in ROM.
  855. The program reads your keystroke and converts it to the corresponding
  856. ASCII code.
  857.      2.  Then the program loops through eight bytes for the character,
  858. with byte zero (the first byte) containing the bits for the top row of
  859. the character and byte seven containing those for the bottom row.  It
  860. stores the value of the PEL map in the variable A and initializes A$
  861. as a null string.
  862.      3.  We begin to loop through the eight bits of the current byte,
  863. resting the rightmost bit first.  The variable M equals one if the bit
  864. is set and equals zero if it's not.  The value of the variable W equals
  865. 32 (the ASCII code for a blank space) if the bit is not set and equals
  866. 219 (the ASCII code for a solid block) if the bit is set.  Either three
  867. blanks or three solid blocks are added to the beginning of A$.  Then
  868. the program shifts all bits in the current byte by subtracting the
  869. value of the rightmost bit and dividing by two.  This step is repeated
  870. for each bit of the current byte.
  871.      4.  The next step is to print A$ preceded by 28 blanks.  This is
  872. done twice to double the character's height.  Then the program
  873. branches back to step 2 and repeats the process for each byte of the
  874. PEL map that defines the character.  After the last byte of the PEL
  875. map has been processed, we print two blank lines and return to step 1
  876. to wait for another keypress.
  877.      Experienced programmers may notice that the code could be made
  878. even more compact.  Some statements could be combined, but this would
  879. result in parentheses several levels deep, making the program more
  880. difficult to understand.
  881.  
  882. 1 KEY OFF:DEF SEG=&HFFA6:L$=INPUT$(1):N=ASC(L$):CLS:LOCATE 24,1,0:FOR
  883.   L=0 TO 7:A=PEEK(N*8+L+14):A$="":FOR J=0 TO 7:M=A AND 1:W=32+M*187:A$
  884.   =CHR$(W)+CHR$(W)+CHR$(W)+A$:A=(A-M)/2:NEXT J:PRINT SPC(28)A$:PRINT
  885.   SPC(28)A$:NEXT L:PRINT:PRINT:GOTO 1
  886.  
  887. (NOTE:  To save and run this one-line program, copy it out and make it
  888. one continuous line by removing the carriage returns from the ends of
  889. the lines.)
  890.  
  891. -----------------------------------------------------------------
  892.                         Faster Slide Show
  893.        (PC Magazine Vol 5 No 21 Dec 9, 1986 User-to-User)
  894.  
  895.      This technique produces a smooth BASIC slide show program.  The
  896. BASIC BLOADer normally reads a graphics screen off a disk directly to
  897. the screen buffer.  This approach gives a very slow (7.5-second) and
  898. messy screen update.  However, using a combination of the PUT statement
  899. and VARPTR function with BLOAD creates a fast and smooth slide show
  900. program.  Use these statements to create screen data files:
  901.  
  902. 100 DIM A(4000)
  903.  .
  904.  .  (Screen-creating code)
  905.  .
  906. 200 GET (0,0)-(319,199),A
  907. 210 DEF SEG
  908. 220 ADDRESS=VARPTR(A(0))
  909. 230 BSAVE "SCR1.",ADDRESS,16004
  910.  
  911. Then use the following statements to display the graphics screens:
  912.  
  913. 100 DIM A(4000)
  914. 110 ADDRESS=VARPTR(A(0))
  915. 120 BLOAD "SCR1.",ADDRESS
  916. 130 PUT (0,0),A,PSET
  917.  
  918.      This method updates the screen in less than a second.  It still
  919. takes about 7.5 seconds to BLOAD the graphics information into memory,
  920. but you can display one screen while the next one loads.  The full
  921. technique is implemented in DEMOLOAD.BAS:
  922.  
  923. 100 'DEMOLOAD.BAS
  924. 110 DEF FNS$(Z)=MID$(STR$(Z),2)
  925. 120 SCREEN 1:CLS:KEY OFF:DIM A(4000)
  926. 130 PRINT "First we'll make 3 screens"
  927. 140 PRINT "(Hit any key to continue)"
  928. 150 WHILE INKEY$="":WEND:CLS
  929. 160 FOR B=1 TO 3:FOR C=1 TO 23
  930. 170 PRINT STRING$(40,48+B);:NEXT
  931. 180 CIRCLE (160,92),60,B,,,4/5
  932. 190 PAINT (160,92),B
  933. 200 GET (0,0)-(319,199),A
  934. 210 DEF SEG:ADDRESS=VARPTR(A(0))
  935. 220 BSAVE "SCR"+FNS$(B),ADDRESS,16004
  936. 230 CLS:NEXT
  937. 240 '
  938. 250 PRINT "Now we'll quick-load them"
  939. 260 PRINT "(Hit any key to continue)"
  940. 270 WHILE INKEY$="":WEND
  941. 280 ADDRESS=VARPTR(A(0))
  942. 290 BLOAD "SCR1",ADDRESS
  943. 300 PUT (0,0),A,PSET
  944. 310 BLOAD "SCR2",ADDRESS
  945. 320 PUT (0,0),A,PSET
  946. 330 BLOAD "SCR3",ADDRESS
  947. 340 PUT (0,0),A,PSET
  948.  
  949. -----------------------------------------------------------------
  950.                          BASICA 3.2 Bug
  951.        (PC Magazine Vol 5 No 22 Dec 23, 1986 User-to-User)
  952.  
  953.      DOS 3.2 BASICA.COM does not save files efficiently.  If a file's
  954. size is reduced, the space allocated is fixed at the largest previously
  955. saved size.  This is not true for all other IBM (Microsoft) BASICs,
  956. including DOS 3.2 BASIC.COM.  The solution is to set up a macro (based
  957. on the filename being imbedded in the program at a fixed location) to
  958. first delete the current file before the updated version is saved.
  959. SmartKey is a big help here.
  960.      Editor's Note:  Another solution is to add two lines to the
  961. beginning of your program:
  962.  
  963. 101 KILL"filename
  964. 102 SAVE"filename
  965.  
  966. (substituting the actual name of your BASICA program for filename).
  967. Each time you run it, this code will delete the existing version and
  968. save the subsequent one.
  969.      Actually, when you chop a large program down to a smaller one,
  970. BASICA 3.2 not only keeps the file size the same but actually seems to
  971. retain the discarded part of the program.  To see this in action
  972. (assuming you're using BASIC 3.2 only), run LONG.BAS to create a 10K
  973. file:
  974.  
  975. 100 'CREATE.BAS -- creates a long file
  976. 110 DEF FNST$(Z)=MID$(STR$(Z),2+(Z<0))
  977. 120 OPEN "LONG.BAS" FOR OUTPUT AS #1
  978. 130 FOR A=100 TO 5000 STEP 10
  979. 140 PRINT #1,FNST$(A);" REM DUMMY TEXT"
  980. 150 NEXT:CLOSE:END
  981.  
  982.      Get into DOS and note the file size.  Then get into BASICA 3.2,
  983. load LONG.BAS, and issue the command to get rid of most of the file's
  984. contents:
  985.  
  986. DELETE 200-
  987.  
  988. Save the shorter file, and get into DOS and you'll see that the tiny
  989. file has the same size as the older, larger one.  Then get into DEBUG,
  990. and start leaning on the D key and you'll see that the part of the file
  991. you deleted is still there.
  992.  
  993.